package com.zhongke.common.imageloader

import android.graphics.Bitmap
import android.graphics.BitmapShader
import android.graphics.Color
import android.graphics.Matrix
import android.graphics.Paint
import android.graphics.Path
import android.graphics.PorterDuff
import android.graphics.RectF
import android.graphics.Shader
import androidx.annotation.Dimension
import androidx.core.graphics.applyCanvas
import androidx.core.graphics.createBitmap
import coil.decode.DecodeUtils
import coil.size.Scale
import coil.size.Size
import coil.size.pxOrElse
import coil.transform.Transformation
import com.zhongke.common.utils.px
import kotlin.math.roundToInt

/**
 *@Date: 2022/5/9
 *@Time: 13:51
 *@Author:cxc
 *@Description:coil的圆角Transformation
 */
class ZKColiRoundCornersTransform(
    @Dimension(unit = Dimension.DP) private var topLeft: Float = 0f,
    @Dimension(unit = Dimension.DP) private var topRight: Float = 0f,
    @Dimension(unit = Dimension.DP) private var bottomLeft: Float = 0f,
    @Dimension(unit = Dimension.DP) private var bottomRight: Float = 0f,
    @CornerType cornerType:Int = CornerType.ALL
) : Transformation {

    //默认以dp作为标准
    constructor(
        @Dimension(unit = Dimension.DP) radius: Float,
        @CornerType cornerType:Int = CornerType.ALL
    ) : this(radius, radius, radius, radius, cornerType)

    init {
        require(topLeft >= 0 && topRight >= 0 && bottomLeft >= 0 && bottomRight >= 0) {
            "All radii must be >= 0."
        }
        when (cornerType) {
            CornerType.ALL -> {
                //do nothing
            }
            CornerType.TOP_LEFT -> {
                topRight = 0f
                bottomLeft = 0f
                bottomRight = 0f
            }
            CornerType.TOP_RIGHT -> {
                topLeft = 0f
                bottomLeft = 0f
                bottomRight = 0f
            }
            CornerType.BOTTOM_LEFT -> {
                topRight = 0f
                topLeft = 0f
                bottomRight = 0f
            }
            CornerType.BOTTOM_RIGHT -> {
                topRight = 0f
                bottomLeft = 0f
                topLeft = 0f
            }
            CornerType.TOP -> {
                bottomLeft = 0f
                bottomRight = 0f
            }
            CornerType.BOTTOM -> {
                topLeft = 0f
                topRight = 0f
            }
            CornerType.LEFT -> {
                topRight = 0f
                bottomRight = 0f
            }
            CornerType.RIGHT -> {
                topLeft = 0f
                bottomLeft = 0f
            }
        }
    }

    override val cacheKey = "${javaClass.name}-$topLeft,$topRight,$bottomLeft,$bottomRight"

    override suspend fun transform(input: Bitmap, size: Size): Bitmap {
        val paint = Paint(Paint.ANTI_ALIAS_FLAG or Paint.FILTER_BITMAP_FLAG)

        val dstWidth = size.width.pxOrElse { input.width }
        val dstHeight = size.height.pxOrElse { input.height }
        val multiplier = DecodeUtils.computeSizeMultiplier(
            srcWidth = input.width,
            srcHeight = input.height,
            dstWidth = dstWidth,
            dstHeight = dstHeight,
            scale = Scale.FILL
        )
        val outputWidth = (dstWidth / multiplier).roundToInt()
        val outputHeight = (dstHeight / multiplier).roundToInt()

        val output =
            createBitmap(outputWidth, outputHeight, input.config ?: Bitmap.Config.ARGB_8888)
        output.applyCanvas {
            drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR)

            val matrix = Matrix()
            matrix.setTranslate(
                (outputWidth - input.width) / 2f,
                (outputHeight - input.height) / 2f
            )
            val shader = BitmapShader(input, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP)
            shader.setLocalMatrix(matrix)
            paint.shader = shader

            val radii = floatArrayOf(
                topLeft.px, topLeft.px,
                topRight.px, topRight.px,
                bottomRight.px, bottomRight.px,
                bottomLeft.px, bottomLeft.px
            )
            val rect = RectF(0f, 0f, width.toFloat(), height.toFloat())
            val path = Path().apply { addRoundRect(rect, radii, Path.Direction.CW) }
            drawPath(path, paint)
        }

        return output
    }

    override fun equals(other: Any?): Boolean {
        if (this === other) return true
        return other is ZKColiRoundCornersTransform &&
                topLeft == other.topLeft &&
                topRight == other.topRight &&
                bottomLeft == other.bottomLeft &&
                bottomRight == other.bottomRight
    }

    override fun hashCode(): Int {
        var result = topLeft.hashCode()
        result = 31 * result + topRight.hashCode()
        result = 31 * result + bottomLeft.hashCode()
        result = 31 * result + bottomRight.hashCode()
        return result
    }
}


